<?php

// ------------------------------------------------------------------------
// |@Author       : Jarmin <edshop@qq.com>
// |@----------------------------------------------------------------------
// |@Date         : 2025-04-18 10:42:36
// |@----------------------------------------------------------------------
// |@LastEditTime : 2025-04-21 13:16:43
// |@----------------------------------------------------------------------
// |@LastEditors  : Jarmin <jarmin@ladmin.cn>
// |@----------------------------------------------------------------------
// |@Description  : 验证码服务类
// |@----------------------------------------------------------------------
// |@FilePath     : Captcha.php
// |@----------------------------------------------------------------------
// |@Copyright (c) 2025 http://www.ladmin.cn   All rights reserved.
// ------------------------------------------------------------------------

namespace think\admin\service;

use think\captcha\exception\ParamException;
use think\captcha\service\ClickWordCaptchaService;
use think\captcha\service\BlockPuzzleCaptchaService;
use think\admin\Service;

/**
 * 验证码服务类
 *
 * 提供验证码生成和验证服务，支持多种验证码类型
 */
class Captcha extends Service
{
    /**
     * 创建验证码
     *
     * @param string $type 验证码类型 (clickWord|blockPuzzle)
     * @return array 返回验证码数据
     * @throws ParamException 当验证码类型不正确时抛出异常
     */
    public function create(string $type)
    {
        return $this->getCaptchaService($type)->get();
    }

    /**
     * 获取验证码服务实例
     *
     * @param string $type 验证码类型 (clickWord|blockPuzzle)
     * @return ClickWordCaptchaService|BlockPuzzleCaptchaService 验证码服务实例
     * @throws ParamException 当验证码类型不正确时抛出异常
     */
    public function getCaptchaService(string $type)
    {
        $config = config('captcha');
        switch ($type) {
            case 'clickWord':
                return new ClickWordCaptchaService($config);
            case 'blockPuzzle':
                return new BlockPuzzleCaptchaService($config);
            default:
                throw new ParamException(lang('service.captcha_type_invalid', ['type' => $type]));
        }
    }

    /**
     * 一次验证
     *
     * @param string $type 验证码类型
     * @param string $token 验证token
     * @param string $pointJson 验证坐标数据
     * @return bool 验证结果
     * @throws ParamException 当验证失败时抛出异常
     */
    public function check(string $type, string $token, string $pointJson)
    {
        $this->getCaptchaService($type)->check($token, $pointJson);
        return true;
    }

    /**
     * 二次验证
     *
     * @param string $type 验证码类型
     * @param string $token 验证token
     * @param string $pointJson 验证坐标数据
     * @return bool 验证结果
     * @throws ParamException 当验证失败时抛出异常
     */
    public function verify(string $type, string $token, string $pointJson)
    {
        $this->getCaptchaService($type)->verification($token, $pointJson);
        return true;
    }

    /**
     * 验证前端传递的验证码数据
     *
     * @param array $verifyData 验证数据
     * @return bool 验证结果
     */
    public function verifyData(array $verifyData)
    {
        try {
            // 验证数据基本格式
            if (empty($verifyData) || !is_array($verifyData)) {
                throw new ParamException(lang('service.captcha_data_format'));
            }

            // 兼容多种前端传参格式
            $token = $verifyData['token'] ?? $verifyData['captchaToken'] ?? '';
            $pointJson = $verifyData['pointJson'] ?? $verifyData['captchaPointJson'] ?? '';
            $type = $verifyData['type'] ?? $verifyData['captchaType'] ?? 'blockPuzzle';

            if (empty($token) || empty($pointJson)) {
                throw new ParamException(lang('service.captcha_data_missing'));
            }

            // 验证验证码
            $this->verify($type, $token, $pointJson);
            return true;
        } catch (\Exception $e) {
            throw $e;
        }
    }
}
